package com.lablzh.gdxy.service.impl;

import com.lablzh.gdxy.component.DynamicOperateExcelUtils;
import com.lablzh.gdxy.component.UserDetailsUtil;
import com.lablzh.gdxy.entity.BonusProject;
import com.lablzh.gdxy.entity.PushfreeProject;
import com.lablzh.gdxy.entity.Sciachievement;
import com.lablzh.gdxy.entity.activity.Project;
import com.lablzh.gdxy.entity.admin.Material;
import com.lablzh.gdxy.entity.admin.News;
import com.lablzh.gdxy.entity.course.Course;
import com.lablzh.gdxy.entity.design.Design;
import com.lablzh.gdxy.repository.BonusProjectRepository;
import com.lablzh.gdxy.repository.PushfreeProjectRepository;
import com.lablzh.gdxy.repository.SciachievementRepository;
import com.lablzh.gdxy.repository.admin.MaterialRepository;
import com.lablzh.gdxy.repository.admin.NewsRepository;
import com.lablzh.gdxy.repository.admin.SubjectRepository;
import com.lablzh.gdxy.repository.course.CourseRepository;
import com.lablzh.gdxy.repository.design.DesignRepository;
import com.lablzh.gdxy.service.CourseService;
import com.lablzh.gdxy.service.FileService;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.apache.commons.fileupload.FileItem;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private CourseRepository courseRepository;

    @Autowired
    private MaterialRepository materialRepository;

    @Autowired
    private UserDetailsUtil userDetailsUtil;

    @Autowired
    private NewsRepository newsRepository;

    @Autowired
    private SubjectRepository subjectRepository;
    private static final String BASEPATH = "./resources/static/";

    @Autowired
    private DesignRepository designRepository;

    @Autowired
    private PushfreeProjectRepository pushfreeProjectRepository;

    @Autowired
    private BonusProjectRepository bonusProjectRepository;

    @Autowired
    private SciachievementRepository sciachievementRepository;

    @Override
    public void downloadFile(String filename,
                             HttpServletRequest request,
                             HttpServletResponse response) throws FileNotFoundException {
        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        try {
            File file = new File(BASEPATH + filename);
            System.out.println(filename);
            fis = new FileInputStream(file);
          //  response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            response.setHeader("Content-Disposition", "attachment; filename=qqqqqq.xlsx");
            IOUtils.copy(fis, response.getOutputStream());
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
//    @Override
//    public Map<String, String> uploadFile(MultipartFile uploadFile, HttpServletRequest req, String username) throws IOException {
//        Map<String,String> result=new HashMap();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
//        if(uploadFile.isEmpty()){
//            result.put("result","请选择上传文件");
//            return result;
//        }
//        File file = new File(BASEPATH);
//        if(!file.isDirectory()){
//                //递归生成文件夹
//                file.mkdirs();
//            }
//        String name = uploadFile.getOriginalFilename();
//        try{
//            //构建真实的文件路径
//            File newFile = new File(file.getAbsolutePath() + File.separator + name);
//        uploadFile.transferTo(newFile);
//        result.put("result","上传成功！");
//        result.put("path",BASEPATH);
//        String date = sdf.format(new Date());
//        result.put("uploadTime",date);
//        return result;
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        result.put("result","上传失败！");
//        return result;
//    }

    @Override
    public Map<String, String> summitFile(
            HttpServletRequest request,
            String category,
            Integer id) throws IOException {
        Map<String, String> result = new HashMap<>();
//        if(summitFile.isEmpty()){
//            result.put("result","请选择上传文件");
//            return result;
//        }
        String filepath = BASEPATH + category + "/" + id.toString() + "/";
        if (category.startsWith("毕业设计")) {
            Design design = designRepository.findById(id).orElse(null);
            String category1 = design.getCategory();
            filepath = BASEPATH + category1 + "/" + category + "/" + id.toString() + "/";
        }
        ServletFileUpload upload = new ServletFileUpload(
                new DiskFileItemFactory());
        upload.setHeaderEncoding("UTF-8");


        System.out.println(filepath);
        File file = new File(filepath);
        if (!file.isDirectory()) {
            //递归生成文件夹
            file.mkdirs();
        }
        String filename = null;
        //构建真实的文件路径
        try {
            List<FileItem> list = upload.parseRequest(request);
            for (FileItem item : list) {
                if (!item.isFormField()) {
                    filename = item.getName();
                    System.out.println(filename);
                    File newFile = new File(file.getAbsolutePath() + File.separator + filename);
                    item.write(newFile);
                }
            }
            result.put("result", "上传成功！");
            result.put("path", filepath);
            LocalDate localDate = LocalDate.now();
            result.put("uploadTime", localDate.toString());
            result.put("filename", filename);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("result", "上传失败！");
        return result;
    }

    @Override
    public void reviewFile(String category,
                           Integer id,
                           String filename,
                           HttpServletRequest request,
                           HttpServletResponse response
    ) throws FileNotFoundException {
        System.out.println(filename);
        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        try {
            String filepath = BASEPATH + category + "/" + id.toString() + "/" + filename;
            if (category.startsWith("毕业设计")) {
                Design design = designRepository.findById(id).orElse(null);
                String category1 = design.getCategory();
                filepath = BASEPATH + category1 + "/" + category + "/" + id.toString() + "/" + filename;
            }
            File file = new File(filepath);
            fis = new FileInputStream(file);
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            IOUtils.copy(fis, response.getOutputStream());
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void downloadEnclosureFile(String category,
                                      Integer id,
                                      String filename,
                                      HttpServletRequest request,
                                      HttpServletResponse response
    ) throws FileNotFoundException {
        System.out.println(filename);
        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        String filepath = "";
        try {
//            if (category.startsWith("毕业设计")) {
//                Design design = designRepository.findById(id).orElse(null);
//                String category1 = design.getCategory();
//                filepath = BASEPATH + category1 + "/" + category + "/" + id.toString() + "/"+filename;
//            }
            switch (category) {
                case "推免": {
                    PushfreeProject pushfreeProject = pushfreeProjectRepository.findById(id).orElse(null);
                    String grade = pushfreeProject.getGrade();
                    String stuCode = pushfreeProject.getStuCode();
                    String name = pushfreeProject.getName();
                    filepath = BASEPATH + grade + category + "/" + stuCode + name + "/" + filename;
                    break;
                }
                case "奖学金": {
                    BonusProject bonusProject = bonusProjectRepository.findById(id).orElse(null);
                    String grade = bonusProject.getGrade();
                    String stuCode = bonusProject.getStuCode();
                    String name = bonusProject.getName();
                    filepath = BASEPATH + grade + category + "/" + stuCode + name + "/" + filename;
                    break;
                }
                case "课外科技成果": {
                    Sciachievement sciachievement = sciachievementRepository.findById(id).orElse(null);
                    String grade = sciachievement.getGrade();
                    String stuCode = sciachievement.getStuCode();
                    String name = sciachievement.getName();
                    filepath = BASEPATH + grade + category + "/" + stuCode + name + "/" + filename;
                    break;
                }
            }
            System.out.println("===========================");
            System.out.println(filepath);
            System.out.println("===========================");
            System.out.println(filename);
            File file = new File(filepath);
            fis = new FileInputStream(file);
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            IOUtils.copy(fis, response.getOutputStream());
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public List<Material> getAllMaterial() {
        return materialRepository.findAll();
    }

    /**
     * 下载课程文件大纲
     *
     * @param id
     * @param request
     * @param response
     * @throws FileNotFoundException
     */
    @Override
    public void downloadCourseFile(String filename, Integer id, HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException {

        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        String filepath = "";
        Course course = courseRepository.findById(id).orElse(null);
        String grade = course.getGrade();
        try {
//            if (category.startsWith("毕业设计")) {
//                Design design = designRepository.findById(id).orElse(null);
//                String category1 = design.getCategory();
//                filepath = BASEPATH + category1 + "/" + category + "/" + id.toString() + "/"+filename;
//            }
            filepath = BASEPATH + grade + "课程设计" + "/" + id + "/" + filename;
            System.out.println("===========================");
            System.out.println(filepath);
            System.out.println("===========================");
            System.out.println(filename);
            File file = new File(filepath);
            fis = new FileInputStream(file);
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            IOUtils.copy(fis, response.getOutputStream());
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 上传课程大纲文件
     *
     * @param request
     * @param id
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, String> summitCourseFile(HttpServletRequest request, Integer id) throws IOException {
        Course course = courseRepository.findById(id).orElse(null);
        String grade = course.getGrade();
        String filename="" ;
        Map<String, String> result = new HashMap<>();
        String filepath = BASEPATH + grade + "课程设计" + "/" + id +"/";
        ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
        upload.setHeaderEncoding("UTF-8");
        System.out.println(filepath);
        File file = new File(filepath);
        if (!file.isDirectory()) {
            //递归生成文件夹
            file.mkdirs();
        }
        //构建真实的文件路径
        try {
            List<FileItem> list = upload.parseRequest(request);
            for (FileItem item : list) {
                if (!item.isFormField()) {
                    filename = item.getName();
                    System.out.println(filename);
                    File newFile = new File(file.getAbsolutePath() + File.separator + filename);
                    item.write(newFile);
                }
            }
            course.setFileName(filename);
            courseRepository.save(course);
            result.put("result", "上传成功！");
            result.put("path", filepath);
            LocalDate localDate = LocalDate.now();
            result.put("uploadTime", localDate.toString());
            result.put("filename", filename);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("result", "上传失败！");
        return result;
    }

    @Override
    public Map<String, String> summitEnclosureFile(
            HttpServletRequest request,
            String category,
            Integer id) throws IOException {
        Map<String, String> result = new HashMap<>();
//        if(summitFile.isEmpty()){
//            result.put("result","请选择上传文件");
//            return result;
//        }
        PushfreeProject pushfreeProject = null;
        Sciachievement sciachievement = null;
        BonusProject bonusProject = null;
        String filepath = "";
        switch (category) {
            case "推免": {
                pushfreeProject = pushfreeProjectRepository.findById(id).orElse(null);
                String grade = pushfreeProject.getGrade();
                String stuCode = pushfreeProject.getStuCode();
                String name = pushfreeProject.getName();
                filepath = BASEPATH + grade + category + "/" + stuCode + name + "/";
                break;
            }
            case "奖学金": {
                bonusProject = bonusProjectRepository.findById(id).orElse(null);
                String grade = bonusProject.getGrade();
                String stuCode = bonusProject.getStuCode();
                String name = bonusProject.getName();
                filepath = BASEPATH + grade + category + "/" + stuCode + name + "/";
                break;
            }
            case "课外科技成果": {
                sciachievement = sciachievementRepository.findById(id).orElse(null);
                String grade = sciachievement.getGrade();
                String stuCode = sciachievement.getStuCode();
                String name = sciachievement.getName();
                filepath = BASEPATH + grade + category + "/" + stuCode + name + "/";
                break;
            }
        }
        ServletFileUpload upload = new ServletFileUpload(
                new DiskFileItemFactory());
        upload.setHeaderEncoding("UTF-8");


        System.out.println(filepath);
        File file = new File(filepath);
        if (!file.isDirectory()) {
            //递归生成文件夹
            file.mkdirs();
        }
        String filename = null;
        //构建真实的文件路径
        try {
            List<FileItem> list = upload.parseRequest(request);
            for (FileItem item : list) {
                if (!item.isFormField()) {
                    filename = item.getName();
                    System.out.println(filename);
                    File newFile = new File(file.getAbsolutePath() + File.separator + filename);
                    item.write(newFile);
                }
            }
            if (pushfreeProject != null) {
                pushfreeProject.setFilePath(filename);
                pushfreeProjectRepository.save(pushfreeProject);
            }
            if (sciachievement != null) {
                sciachievement.setFilePath(filename);
                sciachievementRepository.save(sciachievement);
            }
            if (bonusProject != null) {
                bonusProject.setFilePath(filename);
                bonusProjectRepository.save(bonusProject);
            }
            result.put("result", "上传成功！");
            result.put("path", filepath);
            LocalDate localDate = LocalDate.now();
            result.put("uploadTime", localDate.toString());
            result.put("filename", filename);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("result", "上传失败！");
        return result;
    }

    @Override
    public Boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return file.delete();
        } else {
            return false;
        }
    }

    @Override
    public String addMaterial(HttpServletRequest request, String columns, String category) throws Exception {
        String username = userDetailsUtil.getUserDetails();
        LocalDateTime now = LocalDateTime.now();
        Material material = new Material();
        String filename = null;
        File newFile = null;
        String filepath = BASEPATH + "资料下载/0";
        File file = new File(filepath);
        if (!file.isDirectory()) {
            //递归生成文件夹
            file.mkdirs();
        }
        ServletFileUpload upload = new ServletFileUpload(
                new DiskFileItemFactory());
        upload.setHeaderEncoding("UTF-8");
        List<FileItem> list = upload.parseRequest(request);
        for (FileItem item : list) {
            if (!item.isFormField()) {
                filename = item.getName();
                newFile = new File(file.getAbsolutePath() + File.separator + filename);
                item.write(newFile);
            }
        }
        if (materialRepository.findByFileName(filename) != null) {
            return "该文件已经上传！";
        }
        assert newFile != null;
        material.setFileSize(getFileSize(newFile));
        material.setFileName(filename);
        int index = filename.indexOf(".");
        material.setColumns(columns);
        material.setCategory(category);
        material.setFileType(filename.substring(index));
        material.setUploader(username);
        material.setUploadTime(now);
        materialRepository.save(material);
        return "添加成功！";
    }

    @Override
    public String deleteMaterial(Integer id) {
        Material material = materialRepository.findById(id).orElse(null);
        materialRepository.deleteById(id);
        assert material != null;
        if (deleteFile(BASEPATH + "资料下载/0/" + material.getFileName())) {
            return "删除成功";
        }
        return "删除失败！";
    }

    @Override
    public Map getAllMaterial(Integer page, Integer limit, String column) {
        Material material = new Material();
        material.setColumns(column);
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("columns",ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Material> example = Example.of(material, exampleMatcher);
        Pageable materialPage = PageRequest.of(page - 1, limit, Sort.by(Sort.Direction.DESC, "id"));
        Page<Material> all = materialRepository.findAll(example, materialPage);
        Map<String, Object> data = new HashMap<>();
        data.put("totalPage", all.getTotalPages());
        data.put("total", all.getTotalElements());
        data.put("project", all.getContent());
        return data;
    }

    @Override
    @CacheEvict(cacheNames = "news", allEntries = true)
    public String addNews(News news) {
        LocalDateTime now = LocalDateTime.now();
        if (newsRepository.findByTitle(news.getTitle()) != null) {
            return "该新闻标题已存在";
        }
        news.setUptime(now);
        if (newsRepository.save(news) != null) {
            return "添加成功！";
        } else {
            return "添加失败！";
        }
    }

    @Override
    @CacheEvict(cacheNames = "news", allEntries = true)
    public String updateNews(News news) {
        news.setUptime(LocalDateTime.now());
        newsRepository.save(news);
        return "修改成功！";

    }

    @Override
    @Cacheable(cacheNames = "news")
    public News getOneNews(Integer id) {
        return newsRepository.findById(id).orElse(null);
    }

    @Override
    @Cacheable(cacheNames = "news")
    public News getNewsByTitle(String title) {
        return newsRepository.findByTitle(title);
    }

    @Override
    @Cacheable(cacheNames = "news")
    public List<News> getAllNews() {
        return newsRepository.findAll();
    }

    @Override
    @CacheEvict(cacheNames = "news", allEntries = true)
    public String deleteNews(Integer id) {
        newsRepository.deleteById(id);
        return "删除成功！";
    }

    private String getFileSize(File file) {
        String size;
        if (file.exists() && file.isFile()) {
            long fileS = file.length();
            DecimalFormat df = new DecimalFormat("#.00");
            if (fileS < 1024) {
                size = df.format((double) fileS) + "BT";
            } else if (fileS < 1048576) {
                size = df.format((double) fileS / 1024) + "KB";
            } else if (fileS < 1073741824) {
                size = df.format((double) fileS / 1048576) + "MB";
            } else {
                size = df.format((double) fileS / 1073741824) + "GB";
            }
        } else if (file.exists() && file.isDirectory()) {
            size = "";
        } else {
            size = "0BT";
        }
        return size;
    }

}
